# Name: InstallAndUpdatePipPackages.py #
# 
# Author: Waters #
# Date: 2023.02.01 #
# Version: v0.0.2 #

import os
import re

import GlobalVariables

def CreateGlobalVariables():
	# #define
	global SUCCESS
	global FAILURE
	global ERROR
	SUCCESS = 0
	FAILURE = -1
	ERROR = -2

	globals().update(GlobalVariables.GetAllCustomGlobalVariables())

	global g_szVersionNumber
	g_szVersionNumber = 'v0.0.2'

	return 0

def GetPythonVersion():
	try:
		szResultQueryPythonVersion = os.popen('python.exe -V').readline()
	except Exception as tempError:
		raise tempError
		return ERROR
	else:
		if(re.match('Python', szResultQueryPythonVersion)):
			print('Current Python version is: %s' %szResultQueryPythonVersion)
			return SUCCESS
		else:
			print('Cannot find Python in this machine.\n')
			return FAILURE
	return 0

def InstallPackagesNeeded():
	lszPackagesInstalled = []
	lszPackageNamesInstalled = []
	lszPackageNamesNeed2Install = []
	lszPackageNamesInstalledSucceed = []
	lszPackageNamesInstalledFailed = []
	try:
		lszPackagesInstalled = os.popen("pip list").readlines()
	except Exception as e:
		print('%s\n' %e)
		return ERROR
	else:
		if(lszPackagesInstalled):
			for i in range(2, len(lszPackagesInstalled)):
				lszPackageNamesInstalled.append(lszPackagesInstalled[i].split()[0])
			if(lszPackageNamesInstalled):
				for eachPackage in g_lszPackagesNeeded:
					if(eachPackage in lszPackageNamesInstalled):
						pass
					else:
						lszPackageNamesNeed2Install.append(eachPackage)
			else:
				pass
			# Install
			if(lszPackageNamesNeed2Install):
				print('There are %d packages need to be installed.\n' %(len(lszPackageNamesNeed2Install)))
				for eachPackage in lszPackageNamesNeed2Install:
					try:
						os.system('python.exe -m pip install ' + eachPackage + os.linesep)
					except Exception as e:
						print('%s\n' %e)
						lszPackageNamesInstalledFailed.append(eachPackage)
					else:
						lszPackageNamesInstalledSucceed.append(eachPackage)
				print('\n%s Installed successfully.\n%s Installed failed.\n\n' %(lszPackageNamesInstalledSucceed, lszPackageNamesInstalledFailed))
			else:
				print('All required packages have been installed.\n')
		else:
			print('There are no packages installed in the current environment.\n')

	return 0

def AutoUpdatePip():
	# Check Python version.
	if(SUCCESS == GetPythonVersion()):
		pass
	else:
		return FAILURE

	# Get all installed packages.
	print('Checking installed packages for upgrade...\n')
	try:
		lsPackagesOutdatedResult = os.popen("pip list --outdated").readlines()
	except Exception as tempError:
		raise tempError
		return ERROR
	else:
		lsPackagesOutdatedName = []
		if(lsPackagesOutdatedResult):
			iOutdatedPackageNum = len(lsPackagesOutdatedResult) - 2
			for i in range(2, len(lsPackagesOutdatedResult)):
				lsPackagesOutdatedName.append(lsPackagesOutdatedResult[i].split()[0])
		else:
			iOutdatedPackageNum = 0
		print('There are %d installed packages that need to be upgraded:' %iOutdatedPackageNum)
		print(lsPackagesOutdatedName)
		print('')

	# Update packages
	if(lsPackagesOutdatedName):
		print('Upgrading...\n')
		iCountSucceed = 0
		iCountFailed = 0
		szFailedPackages = []
		for eachPackage in lsPackagesOutdatedName:
			try:
				# print('python.exe -m pip install --upgrade ' + eachPackage + os.linesep)
				os.system('python.exe -m pip install --upgrade ' + eachPackage + os.linesep)
			except Exception as tempError:
				iCountFailed += 1
				szFailedPackages.append(eachPackage)
				raise tempError
			else:
				iCountSucceed += 1
	else:
		return SUCCESS
	print('\n%d packages upgrade successfully.\n' %iCountSucceed)
	if(iCountFailed):
		print('%d packages upgrade failed:' %iCountFailed)
		print(szFailedPackages)
	else:
		pass

	return 0


if __name__ == '__main__':
	CreateGlobalVariables()
	print('AutoInstallAndUpdatePackages_%s:\n' %g_szVersionNumber)
	InstallPackagesNeeded()
	AutoUpdatePip()